package com.googlecode.cswish.struts.hibernate;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * A structure to store the changed model information
 */
public class DynamicModelInfo implements Serializable {

	private static final long serialVersionUID = 2504080590294301051L;
	
	private String modelName;
	private boolean dynamic;
	
	// property name <--> property type, the new property information
	private Map<String, DPropertyInfo> properties;
	// property name <--> ModelField id
	private Map<String, DPropertyInfo> removedProperties;
	
	public DynamicModelInfo() {
		this(null);
	}
	
	public DynamicModelInfo(String modelName) {
		this.dynamic = true;
		this.modelName = modelName;
		this.properties = new HashMap<String, DPropertyInfo>();
	}

	public DynamicModelInfo(String modelName, Map<String, DPropertyInfo> properties) {
		this.dynamic = true;
		this.modelName = modelName;
		if (properties != null) {
			this.properties = properties;
		}
	}
	
	public String getModelName() {
		return modelName;
	}

	public void setModelName(String modelName) {
		this.modelName = modelName;
	}

	public void addProperty(String name, String type, String genericType, boolean transientProperty, boolean hasDbColumn
			, int length, boolean nullable, boolean unique) {
		DPropertyInfo dpropertyInfo = new DPropertyInfo();
		dpropertyInfo.name = name;
		dpropertyInfo.type = type;
		dpropertyInfo.genericType = genericType;
		dpropertyInfo.transientProperty = transientProperty;
		dpropertyInfo.hasDbColumn = hasDbColumn;
		dpropertyInfo.length = length;
		dpropertyInfo.nullable = nullable;
		dpropertyInfo.unique = unique;
		properties.put(name, dpropertyInfo);
	}
	
	public void addRemovedProperty(String name) {
		DPropertyInfo dpropertyInfo = new DPropertyInfo();
		dpropertyInfo.name = name;
		if (removedProperties == null) {
			removedProperties = new HashMap<String, DPropertyInfo>();
		}
		removedProperties.put(name, dpropertyInfo);
	}
	
	public Map<String, DPropertyInfo> getProperties() {
		return properties;
	}

	public void setProperties(Map<String, DPropertyInfo> properties) {
		this.properties = properties;
	}

	public DPropertyInfo getProperty(String fieldName) {
		return properties.get(fieldName);
	}
	
	public DPropertyInfo getRemovedProperty(String fieldName) {
		if (removedProperties == null) {
			return null;
		}
		return removedProperties.get(fieldName);
	}
	
	public String getPropertyI18nKey(String property) {
		DPropertyInfo propertyInfo = properties.get(property);
		String i18nKey = propertyInfo == null ? null : propertyInfo.i18nKey;
		return i18nKey == null ? property : i18nKey;
	}
	
	public String getRemovedPropertyI18nKey(String property) {
		if (removedProperties == null) {
			return null;
		}
		DPropertyInfo propertyInfo = removedProperties.get(property);
		String i18nKey = propertyInfo == null ? null : propertyInfo.i18nKey;
		return i18nKey == null ? property : i18nKey;
	}

	public Map<String, DPropertyInfo> getRemovedProperties() {
		return removedProperties;
	}

	public void setRemovedProperties(Map<String, DPropertyInfo> removedProperties) {
		this.removedProperties = removedProperties;
	}
	
	public boolean isDynamic() {
		return dynamic;
	}

	public void setDynamic(boolean dynamic) {
		this.dynamic = dynamic;
	}

	@Override
	public String toString() {
		return this.modelName; 
	}

	public void addPropertyI18n(String fieldName, String i18nKey) {
		DPropertyInfo propertyInfo = properties.get(fieldName);
		if (propertyInfo != null) {
			propertyInfo.i18nKey = i18nKey;
		}
	}

	public void removePropertyI18n(String fieldName) {
		DPropertyInfo propertyInfo = properties.get(fieldName);
		if (propertyInfo != null) {
			propertyInfo.i18nKey = null;
		}
	}

	public void setPropertyToTransient(String fieldName, boolean transientProperty) {
		DPropertyInfo dpropertyInfo = properties.get(fieldName);
		if (dpropertyInfo != null) {
			dpropertyInfo.transientProperty = transientProperty;
		}
	}

	public void merge(DynamicModelInfo another) {
		properties.putAll(another.properties);
		
		if (another.removedProperties != null) {
			if (this.removedProperties == null) {
				this.removedProperties = new HashMap<String, DPropertyInfo>();
			}
			this.removedProperties.putAll(another.removedProperties);
		}
	}
}